Ext.define('Ext.ux.grid.plugin.ToolFilter',{
	extend : 'Ext.AbstractPlugin',
	requires : [ 'Ext.grid.filters.filter.*' ],
	mixins : [ 'Ext.util.Bindable' ],
	alias : 'plugin.gfilters',
	pluginId : 'gfilters',
	defaultFilterTypes : {
		'boolean' : 'boolean',
		'int' : 'number',
		date : 'date',
		number : 'number'
	},
	filterCls : Ext.baseCSSPrefix+ 'grid-filters-filtered-column',
	menuFilterText : 'Filters',
	showMenu : true,
	stateId : undefined,
	init : function(grid) {
		var me = this, store, headerCt;
		me.grid = grid;
		grid.filters = me;
		if (me.grid.normalGrid) {
			me.isLocked = true;
		}
		grid.clearFilters = me.clearFilters.bind(me);
		store = grid.store;
		headerCt = grid.headerCt;
		// c4w 将菜单从列头位置改到工具栏，不再为列头菜单生成filter菜单项
		/*
		* headerCt.on({ scope: me, add: me.onAdd, menucreate:
		* me.onMenuCreate });
		*/
		grid.on({
			scope : me,
			destroy : me.onGridDestroy,
			beforereconfigure : me.onBeforeReconfigure,
			reconfigure : me.onReconfigure
		});
		me.bindStore(store);
		if (grid.stateful) {
			store.statefulFilters = true;
		}
		me.initColumns();
	},
	initColumns : function() {
		var grid = this.grid, store = grid.getStore(), 
		columns = grid.columnManager.getColumns(), len = columns.length, i, column, filter, filterCollection, block;
		var me = this;
		var its = [];
		for (i = 0; i < len; i++) {
			column = columns[i];
			filter = column.filter;
			if (filter && !filter.isGridFilter) {
				if (!filterCollection) {
					//filterCollection = store.getFilters();
					filterCollection = store.filters;
					//filterCollection.beginUpdate();
				}
				this.createColumnFilter(column);
				//column.filter.createMenu();
				its.push({
				    text : column.text,
					checked : false,
					menu : column.filter.menu,
					filter : column.filter,
					listeners : {
						scope : me,
						checkchange : me.onCheckChange,
						activate : me.onBeforeActivate
					}
				});
			}
		}
		//
		var tbar = grid.down('toolbar');
		tbar.insert(0, {
			xtype : 'splitbutton',
			text : '检索',
			iconCls : null,
			menu : its,
			handler : 'onClearFilters',
			scope : me
		});
		if (filterCollection) {
			//filterCollection.endUpdate();
		}
	},
	onClearFilters : function() {
		this.clearFilters();
	},
	createColumnFilter : function(column) {
		var me = this, 
		columnFilter = column.filter, 
		filter = {
				column : column,
				grid : me.grid,
				owner : me
		}, field, model, type;
		if (Ext.isString(columnFilter)) {
			filter.type = columnFilter;
		} else {
			Ext.apply(filter, columnFilter);
		}
		if (!filter.type) {
			model = me.store.getModel();
			field = model && model.getField(column.dataIndex);
			type = field && field.type;
			filter.type = (type && me.defaultFilterTypes[type]) || column.defaultFilterType || 'string';
		}
		var FilterClass = me.getFilterClass(filter.type);
		column.filter = filter.menu ? filter : new FilterClass(Ext.apply({
            grid: me.grid
        }, filter));
		//column.filter = Ext.Factory.gridFilter(filter);
	},
	getFilterClass : function (type) {
        // map the supported Ext.data.Field type values into a supported filter
        switch(type) {
            case 'auto':
              type = 'string';
              break;
            case 'int':
            case 'float':
              type = 'numeric';
              break;
            case 'bool':
              type = 'boolean';
              break;
        }
        return Ext.ClassManager.getByAlias('gridfilter.' + type);
    },
	onAdd : function(headerCt, column, index) {
		var filter = column.filter;
		if (filter && !filter.isGridFilter) {
			this.createColumnFilter(column);
		}
	},
	onMenuCreate : function(headerCt, menu) {
		menu.on({
			beforeshow : this.onMenuBeforeShow,
		    scope : this
		});
	},
	onMenuBeforeShow : function(menu) {
		var me = this, menuItem, filter, ownerGrid, ownerGridId;
		if (me.showMenu) {
			if (!me.menuItems) {
				me.menuItems = {};
			}
			ownerGrid = menu.up('grid');
			ownerGridId = ownerGrid.id;
			menuItem = me.menuItems[ownerGridId];
			if (!menuItem || menuItem.isDestroyed) {
				menuItem = me.createMenuItem(menu, ownerGridId);
			}
			me.activeFilterMenuItem = menuItem;
			filter = me.getMenuFilter(ownerGrid.headerCt);
			if (filter) {
				filter.showMenu(menuItem);
			}
			menuItem.setVisible(!!filter);
			me.sep.setVisible(!!filter);
		}
	},
	createMenuItem : function(menu, ownerGridId) {
		var me = this, item;
		me.sep = menu.add('-');
		item = menu.add({
				checked : false,
				itemId : 'filters',
				text : me.menuFilterText,
				listeners : {
					scope : me,
					checkchange : me.onCheckChange
				}
		});
		return (me.menuItems[ownerGridId] = item);
	},
	onGridDestroy : function() {
		var me = this, menuItems = me.menuItems, item;
		me.bindStore(null);
		me.sep = Ext.destroy(me.sep);
		for (item in menuItems) {
			menuItems[item].destroy();
		}
		me.grid = null;
	},
	onUnbindStore : function(store) {
		store.getFilters().un('remove', this.onFilterRemove,this);
	},
	onBindStore : function(store, initial, propName) {
		//this.local = !store.getRemoteFilter();
		this.local = !store.remoteFilter;
		//store.getFilters().on('remove', this.onFilterRemove,this);
		store.filters.on('remove', this.onFilterRemove,this); 
	},
	onFilterRemove : function(filterCollection, list) {
		var len = list.items.length, columnManager = this.grid.columnManager, i, item, header, filter;
		for (i = 0; i < len; i++) {
			item = list.items[i];
			header = columnManager.getHeaderByDataIndex(item.getProperty());
			if (header) {
				filter = header.filter;
				if (!filter || !filter.menu || item.getId().indexOf(filter.getBaseIdPrefix()) === -1) {
					continue;
				}
				if (!filter.preventFilterRemoval) {
					filter.onFilterRemove(item.getOperator());
				}
			}
		}
	},
	getMenuFilter : function(headerCt) {
		return headerCt.getMenu().activeHeader.filter;
	},
	onBeforeActivate : function(item, value) {
		this.activeFilterMenuItem = item;
		this.activeFilterMenuItem.activeFilter = item.filter;
	},
	onCheckChange : function(item, value) {
		var grid = this.isLocked ? item.up('grid') : this.grid, filter = item.filter;
		filter.setActive(value);
	},
	getHeaders : function() {
		return this.grid.view.headerCt.columnManager.getColumns();
	},
	isStateful : function() {
		return this.grid.stateful;
	},
	addFilter : function(filters) {
		var me = this, grid = me.grid, store = me.store, hasNewColumns = false, suppressNextFilter = true, dataIndex, column, i, len, filter, columnFilter;
		if (!Ext.isArray(filters)) {
			filters = [ filters ];
		}
		for (i = 0, len = filters.length; i < len; i++) {
			filter = filters[i];
			dataIndex = filter.dataIndex;
			column = grid.columnManager.getHeaderByDataIndex(dataIndex);
			if (column) {
				hasNewColumns = true;
				if (filter.value) {
					suppressNextFilter = false;
				}
				columnFilter = column.filter;
				if (columnFilter && columnFilter.isGridFilter) {
					columnFilter.deactivate();
					columnFilter.destroy();
					if (me.activeFilterMenuItem) {
						me.activeFilterMenuItem.menu = null;
					}
				}
				column.filter = filter;
			}
		}
		if (hasNewColumns) {
			store.suppressNextFilter = suppressNextFilter;
			me.initColumns();
			store.suppressNextFilter = false;
		}
	},
	addFilters : function(filters) {
		if (filters) {
			this.addFilter(filters);
		}
	},
	clearFilters : function(autoFilter) {
		var grid = this.grid, columns = grid.columnManager.getColumns(),
		store = grid.store, oldAutoFilter = store.getAutoFilter(), 
		column, filter, i, len, filterCollection;
		if (autoFilter !== undefined) {
			store.setAutoFilter(autoFilter);
		}
		for (i = 0, len = columns.length; i < len; i++) {
			column = columns[i];
			filter = column.filter;
			if (filter && filter.isGridFilter) {
				if (!filterCollection) {
					//filterCollection = store.getFilters();
					filterCollection = store.filters;
					filterCollection.beginUpdate();
				}
				filter.setActive(false);
			}
		}
		if (filterCollection) {
			filterCollection.endUpdate();
		}
		if (autoFilter !== undefined) {
			store.setAutoFilter(oldAutoFilter);
		}
	},
	onBeforeReconfigure : function(grid, store, columns) {
		if (store) {
			store.getFilters().beginUpdate();
		}
		this.reconfiguring = true;
	},
	onReconfigure : function(grid, store, columns, oldStore) {
		var me = this;
		if (store && oldStore !== store) {
			me.bindStore(store);
		}
		if (columns) {
			me.initColumns();
		}
		if (store) {
			store.getFilters().endUpdate();
		}
		me.reconfiguring = false;
	}
});